package biolabs.visual.j2d;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

import biolabs.sink.Sink;

public class Java2DImageSink implements Sink<Java2DPainter> {

	public enum MarginMode {
		CROP,
		FILL,
	}

	private final Sink<? super BufferedImage> sink;

	private final int width;
	private final int height;

	private boolean keepAspectRatio = true;
	private MarginMode marginMode = MarginMode.FILL;
	private Color backgroundColor = new Color(0, 0, 0, 0);

	public Java2DImageSink(int width, int height, Sink<? super BufferedImage> sink) {

		if(width <= 0 || height <= 0)
			throw new IllegalArgumentException("Width and height must be positive. Found: " + width + "x" + height);

		this.sink = sink;
		this.width = width;
		this.height = height;
	}

	public void setKeepAspectRatio(boolean keepAspectRatio) {
		this.keepAspectRatio = keepAspectRatio;
	}

	public void setMarginMode(MarginMode mode) {
		this.marginMode = mode;
	}

	public void setBackgroundColor(Color color) {
		this.backgroundColor = color;
	}

	@Override
	public void close() {
		sink.close();
	}

	@Override
	public void flush() {
		sink.flush();
	}

	@Override
	public void push(long time, Java2DPainter painter) {
		BufferedImage img;
		Rectangle imgBounds;
		if(!keepAspectRatio) {
			img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
			imgBounds = new Rectangle(0, 0, width, height);
		} else {
			Rectangle bounds = painter.getBounds();
			int w, h;
			double wH = width * bounds.getHeight();
			double Wh = bounds.getWidth() * height;
			if(wH > Wh) {
				// fit height
				w = (int) Math.floor(Wh / bounds.getHeight());
				h = height;
			} else {
				// fit width
				w = width;
				h = (int) Math.floor(wH / bounds.getWidth());
			}

			if(marginMode == MarginMode.CROP) {
				img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
				imgBounds = new Rectangle(0, 0, w, h);
			} else {
				int offx = (width-w) / 2;
				int offy = (height-h) / 2;
				img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
				imgBounds = new Rectangle(offx, offy, w, h);
			}
		}

		Graphics2D g2d = img.createGraphics();
		g2d.setBackground(backgroundColor);
		g2d.clearRect(0, 0, img.getWidth(), img.getHeight());
		g2d.setColor(Color.BLACK);
		g2d.setClip(imgBounds);
		Java2DWindowSink.autofit(g2d, painter.getBounds());
		painter.paint(g2d);
		sink.push(time, img);
		g2d.dispose();
	}

}
